home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk3 / 68kasm / src / adirect.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  21KB  |  705 lines

  1. /*------------------------------------------------------------------*/
  2. /*                                    */
  3. /*              MC68000 Cross Assembler                */
  4. /*                                    */
  5. /*          Copyright    (c) 1985 by Brian R. Anderson            */
  6. /*                                    */
  7. /*      Assembler directive processing - March 20, 1988        */
  8. /*                                    */
  9. /*   This program may be copied    for personal, non-commercial use    */
  10. /*   only, provided that the above copyright notice is included        */
  11. /*   on    all copies of the source code.    Copying    for any    other use   */
  12. /*   without the consent of the    author is prohibited.            */
  13. /*                                    */
  14. /*------------------------------------------------------------------*/
  15. /*                                    */
  16. /*        Originally published (in Modula-2) in            */
  17. /*        Dr.    Dobb's Journal, April, May, and June 1986.          */
  18. /*                                    */
  19. /*    AmigaDOS conversion copyright (c) 1988 by Charlie Gibbs.    */
  20. /*                                    */
  21. /*------------------------------------------------------------------*/
  22.  
  23. #include <stdio.h>
  24. #include "a68kdef.h"
  25. #include "a68kglb.h"
  26.  
  27. /* Functions */
  28. extern int  LineParts(), GetField(), Instructions();
  29. extern int  GetSize(), GetInstModeSize(), GetMultReg();
  30. extern int  ReadSymTab(), GetArgs(), GetAReg(),    OpenIncl();
  31. extern long AddrBndW(),    AddrBndL(), GetValue(),    CalcValue();
  32. extern char *malloc();
  33. extern FILE *fopen();
  34.  
  35.  
  36.  
  37. int ObjDir (f) FILE *f;
  38. /* Generates Object Code for Assembler Directives */
  39. {
  40.     register int i, j;
  41.     int     oploc,    dummy;
  42.     long templong;
  43.     char tempop[MAXLINE], delim;
  44.  
  45.     AddrAdv = 0;
  46.  
  47.     if (strcmp (OpCode,    "ORG") == 0) {                  /* ORG */
  48.     templong = GetValue (SrcOp, SrcLoc);
  49.     if (Hunk2 < 0)
  50.         Error (SrcLoc, RelErr);    /* Can't ORG externally */
  51.     else if    (DefLine2 > LineCount)
  52.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  53.     else {
  54.         AddrCnt = templong;
  55.         CurrHunk = Hunk2;
  56.     }
  57.     PrntAddr = MakeHunk = TRUE;
  58.     return (Org);
  59.     }
  60.  
  61.     if ((strcmp    (OpCode, "EQU") == 0)                   /* EQU */
  62.     || (strcmp (OpCode,    "=") == 0)) {                   /* = */
  63.     if (Label[0] ==    '\0')
  64.         Error (0, NeedLab);        /* Need    a label    */
  65.     ObjSrc = GetValue (SrcOp, SrcLoc);
  66.     if (DefLine2 > LineCount)
  67.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  68.     Src.Hunk = Hunk2;
  69.     PrntAddr = MakeHunk = TRUE;
  70.     return (Equ);
  71.     }
  72.  
  73.     if (strcmp (OpCode,    "DC") == 0) {                   /* DC */
  74.     if ((Size == Word) || (Size == Long))
  75.         AddrCnt = AddrBndW (AddrCnt);
  76.     i = SrcLoc;
  77.     while ((Line[i]    != ' ') && (Line[i] != '\0')) {
  78.         oploc = i;
  79.         if ((Line[i] == '\'') || (Line[i] == '"')) {    /* String */
  80.         delim =    Line[i++];        /* Get the delimiter */
  81.         while (1) {
  82.             if (Line[i]    == '\0') {      /* No closing delimiter */
  83.             Error (SrcLoc +    i, NoStrEnd);
  84.             break;
  85.             }
  86.             if (Line[i]    == delim) { /* End of string? */
  87.             if (Line[++i] != delim)    /* Check next character    */
  88.                 break;        /* End of string */
  89.             }    /* Otherwise it's an apostrophe in the string */
  90.             Src.Hunk = ABSHUNK;            /* Absolute    value */
  91.             ObjString[nX++] = Line[i++];    /* Current char. */
  92.         }
  93.         } else {            /* Not a string    constant */
  94.         i = GetField (Line, i, SrcOp);
  95.         ObjSrc = GetValue (SrcOp, oploc);    /* Value */
  96.         if ((Src.Hunk =    Hunk2) != ABSHUNK) {    /* Hunk    no. */
  97.             templong = AddrCnt + nX;        /* Relocatable */
  98.             PutRel (templong, Hunk2, Size);
  99.         }
  100.         if (Size == 4) {
  101.             ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
  102.             ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
  103.         }
  104.         if (Size >= 2)
  105.             ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
  106.         ObjString[nX++]    = ObjSrc & 0x00FF;
  107.         }
  108.         if (Line[i]    == ',')
  109.         i++;            /* Skip    over separator */
  110.     }
  111.     if ((Line[i] !=    '\0') && (Line[i] != ' '))
  112.         Error (i, OperErr);        /* Didn't end properly */
  113.     AddrAdv    = InstSize = nX;
  114.     PrntAddr = MakeHunk = TRUE;
  115.     return (DC);
  116.     }
  117.  
  118.     if (strcmp (OpCode,    "DS") == 0) {                   /* DS */
  119.     AddrAdv    = GetValue (SrcOp, SrcLoc);
  120.     if (DefLine2 > LineCount) {
  121.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  122.         AddrAdv = 0;
  123.     }
  124.     if (Hunk2 != ABSHUNK)
  125.         Error (SrcLoc, AbsReq);    /* Count must be absolute */
  126.  
  127.     if (Size == Word) {        /* Words */
  128.         AddrCnt = AddrBndW (AddrCnt);
  129.         AddrAdv <<=    1;
  130.     }
  131.     if (Size == Long) {        /* Long    words */
  132.         AddrCnt = AddrBndW (AddrCnt);
  133.         AddrAdv <<=    2;
  134.     }
  135.     if (Pass2 && (HunkType != HunkBSS)) {    /* If this isn't     */
  136.         templong = AddrAdv;            /*  a BSS hunk,         */
  137.         while (templong >= 4) {        /*  generate zeros   */
  138.         AppendSdata (f,    0L, 4);        /*  to fill the    area */
  139.         templong -= 4;
  140.         }
  141.         if (templong > 0) {
  142.         i = templong;
  143.         AppendSdata (f,    0L, i);
  144.         }
  145.     }
  146.     if (DestLoc != 0)
  147.         Error (DestLoc, OperErr);    /* Only    one operand is allowed */
  148.  
  149.     PrntAddr = MakeHunk = TRUE;
  150.     return (DS);
  151.     }
  152.  
  153.     if (strcmp (OpCode,    "EVEN") == 0) {                /* EVEN */
  154.     AddrCnt    = AddrBndW (AddrCnt);
  155.     PrntAddr = MakeHunk = TRUE;
  156.     return (Even);
  157.     }
  158.  
  159.     if (strcmp (OpCode,    "END") == 0) {                  /* END */
  160.     if (Pass2)
  161.         if (SrcOp[0] != '\0')
  162.         EndAddr    = GetValue (SrcOp, SrcLoc);
  163.         else
  164.         EndAddr    = 0;
  165.     PrntAddr = MakeHunk = TRUE;
  166.     return (End);
  167.     }
  168.  
  169.     if (strcmp (OpCode,    "XDEF") == 0) {                 /* XDEF */
  170.     if (SFormat)
  171.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  172.     i = SrcLoc;
  173.     while ((Line[i]    != ' ') && (Line[i] != '\0')) {
  174.         oploc = i;
  175.         i =    GetField (Line,    i, SrcOp);    /* Get a symbol    */
  176.         if (ReadSymTab (SrcOp)) {
  177.         if (!Pass2) {
  178.             if ((Sym->Flags & 0x60) == 0)
  179.             Sym->Flags |= 2;    /* Set XDEF flag */
  180.         } else {
  181.             AddRef (LineCount);
  182.             if (Sym->Defn == NODEF)
  183.             Error (oploc, Undef);    /* Never got defined */
  184.             else if (Sym->Flags    & 0x60)
  185.             Error (oploc, AddrErr);    /* Can't XDEF a register */
  186.         }
  187.         } else if (!Pass2) {        /* Not yet defined */
  188.         AddSymTab (SrcOp, 0L, CurrHunk,    NODEF, 2);
  189.         }
  190.         if (Line[i]    == ',')
  191.         i++;                /* Skip    over separator */
  192.     }
  193.     return (Xdef);
  194.     }
  195.  
  196.     if (strcmp (OpCode,    "XREF") == 0) {                 /* XREF */
  197.     if (SFormat)
  198.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  199.     i = SrcLoc;
  200.     while ((Line[i]    != ' ') && (Line[i] != '\0')) {
  201.         oploc = i;
  202.         i =    GetField (Line,    i, SrcOp);
  203.         if (Pass2) {
  204.         if (ReadSymTab (SrcOp) && (Sym->Defn !=    LineCount)) {
  205.             AddRef (LineCount);    /* Ignore extraneous XREF */
  206.         }
  207.         } else {
  208.         if (!ReadSymTab    (SrcOp)) {        /* Only    if not */
  209.             templong = ~(HeapLim - Heap);    /*   defined   */
  210.             templong &=    0x0000FFFF;
  211.             AddSymTab (SrcOp, 0L, templong, LineCount, 1);
  212.         }
  213.         }
  214.         if (Line[i]    == ',')
  215.         i++;            /* Skip    over separator */
  216.     }
  217.     return (Xref);
  218.     }
  219.  
  220.     if (strcmp (OpCode,    "PAGE") == 0) {                 /* PAGE */
  221.     if (Pass2)
  222.         LnCnt = LnMax;        /* Resume on a new page    */
  223.     return (Page);
  224.     }
  225.  
  226.     if (strcmp (OpCode,    "LIST") == 0) {                 /* LIST */
  227.     ListOff    = FALSE;
  228.     return (DoList);
  229.     }
  230.  
  231.     if ((strcmp(OpCode,"NOLIST")==0) || (strcmp(OpCode,"NOL")==0)) {
  232.     ListOff    = TRUE;                    /* NOLIST */
  233.     return (NoList);
  234.     }
  235.  
  236.     if (strcmp (OpCode,    "SPC") == 0) {                  /* SPC */
  237.     if (Pass2 && !ListOff && !SuppList) {
  238.         if (SrcOp[0] != '\0')
  239.         j = GetValue (SrcOp, SrcLoc);    /* Amount to space */
  240.         else
  241.         j = 1;                /* Default to one line */
  242.         for    (i = 0;    i < j; i++) {
  243.         if (LnCnt >= LnMax)
  244.             break;            /* Page    overflow */
  245.         fprintf    (List, "\n");           /* Space one line */
  246.         }
  247.     }
  248.     return (Space);
  249.     }
  250.  
  251.     if (strcmp (OpCode,    "TTL") == 0) {                  /* TTL */
  252.     for (i = SrcLoc, j = 0;    Line[i]    != '\0'; i++) {
  253.         TTLstring[j++] = Line[i];    /* Get title string */
  254.         if (j >= MAXLINE - 1)
  255.         break;            /* The string is full */
  256.     }
  257.     TTLstring[j] = '\0';
  258.     LnCnt =    LnMax;            /* Skip    to a new page */
  259.     return (Title);
  260.     }
  261.  
  262.     if (strcmp (OpCode,    "CNOP") == 0) {                 /* CNOP */
  263.     i = TRUE;            /* "Error-free" flag */
  264.  
  265.     ObjSrc = GetValue (SrcOp, SrcLoc);
  266.     if (DefLine2 > LineCount) {
  267.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  268.         i =    FALSE;
  269.     }
  270.     if (Hunk2 != ABSHUNK) {
  271.         Error (SrcLoc, AbsReq);    /* Must    be absolute! */
  272.         i =    FALSE;
  273.     }
  274.  
  275.     ObjDest    = GetValue (DestOp, DestLoc);
  276.     if (DefLine2 > LineCount) {
  277.         Error (DestLoc, FwdRef);    /* Illegal forward reference */
  278.         i =    FALSE;
  279.     }
  280.     if (Hunk2 != ABSHUNK) {
  281.         Error (DestLoc, AbsReq);    /* Must    be absolute! */
  282.         i =    FALSE;
  283.     }
  284.  
  285.     templong = ObjDest;
  286.     while ((templong > 0) && ((templong & 1) == 0))
  287.         templong >>= 1;        /* Shift out low-order zeros */
  288.     if ((templong != 1) || (ObjDest    == 1)) {
  289.         Error (DestLoc, OperErr);    /* DestOp must be a power of 2 */
  290.         i =    FALSE;
  291.     }
  292.     if ((ObjSrc & 1) || (ObjSrc >= ObjDest)) {
  293.         Error (SrcLoc, OperErr);    /* SrcOp is odd    or out of range    */
  294.         i =    FALSE;
  295.     }
  296.  
  297.     if (i) {            /* If no errors    so far */
  298.         AddrCnt = AddrBndW (AddrCnt);
  299.         templong = (AddrCnt    & ~(ObjDest-1))    + ObjSrc;
  300.         if (templong < AddrCnt)
  301.         templong += ObjDest;    /* We must advance to here */
  302.         if ((templong - AddrCnt) < MAXLINE)    {
  303.         nX = templong -    AddrCnt;
  304.         for (j = 0; j <    nX; ) {
  305.             ObjString[j++] = NOP / 256;
  306.             ObjString[j++] = NOP & 255;
  307.         }
  308.         AddrAdv    = InstSize = nX;    /* generate NOPs */
  309.         PrntAddr = MakeHunk = TRUE;
  310.         } else {
  311.         Error (DestLoc,    OperErr);    /* Too many NOPs */
  312.         }
  313.     }
  314.     return (Cnop);
  315.     }
  316.  
  317.     if (strcmp (OpCode,    "INCLUDE") == 0) {              /* INCLUDE */
  318.     i = SrcLoc;
  319.     if ((Line[i] ==    '"') || (Line[i] == '\''))
  320.         i++;            /* Ignore quotes */
  321.     j = 0;
  322.     while ((Line[i]    != ' ')
  323.     && (Line[i] != '"')
  324.     && (Line[i] != '\'')
  325.     && (Line[i] != '\0'))
  326.         tempop[j++]    = Line[i++];
  327.     tempop[j] = '\0';
  328.     if (InF->UPtr == 0)
  329.         InF->Pos = ftell(InFile);    /* Position in outer file */
  330.     if (!OpenIncl (tempop, InclList)) {
  331.         Error (SrcLoc, NoIncl);    /* Couldn't open file */
  332.         if (InF->UPtr == 0)    {
  333.         InFile = fopen (InF->NPtr, "r");
  334.         fseek (InFile, InF->Pos, 0);
  335.         }
  336.         return (Include);        /* Return to outer file    */
  337.     }
  338.     InFNum++;                /* Bump    nesting    level */
  339.     if (--InF < LowInF)
  340.         LowInF = InF;
  341.     Heap2Space (strlen (tempop) + 1);    /* Check for space */
  342.     InF->UPtr = 0;                /* Not a user macro */
  343.     InF->NPtr = NextFNS;            /* New stack pointer */
  344.     strcpy (NextFNS, tempop);        /* File    name */
  345.     NextFNS    += strlen (tempop) + 1;        /* Next    available space    */
  346.     if (NextFNS > High2)
  347.         High2 = NextFNS;            /* Set high-water mark */
  348.     InF->NArg = -1;                /* Flag    as an INCLUDE */
  349.     InF->Line = 0;                /* Clear line counter */
  350.     return (Include);
  351.     }
  352.  
  353.     if (strcmp (OpCode,    "SET") == 0) {                  /* SET */
  354.     if (Label[0] ==    '\0')
  355.         Error (0, NeedLab);        /* Need    a label    */
  356.     ObjSrc = GetValue (SrcOp, SrcLoc);
  357.     if (DefLine2 > LineCount)
  358.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  359.     Src.Hunk = Hunk2;
  360.     if (!ReadSymTab    (Label))        /* Make    a new entry */
  361.         AddSymTab (Label, ObjSrc, Src.Hunk,    LineCount, 4);
  362.     else if    (Sym->Flags & 4) {        /* Re-SET the symbol */
  363.         Sym->Val = ObjSrc;            /* SET value */
  364.         Sym->Hunk =    Src.Hunk;        /* Hunk    number */
  365.         Sym->Defn =    LineCount;        /* Statement number */
  366.     }
  367.     PrntAddr = MakeHunk = TRUE;
  368.     return (Set);
  369.     }
  370.  
  371.     if (strcmp (OpCode,    "MACRO") == 0) {                /* MACRO */
  372.     Dir = Macro;
  373.     tempop[0] = ' ';
  374.     i = 0;                /* Prepend name    with a */
  375.     j = 1;                /*  blank and convert */
  376.     while (Label[i])        /*  it to upper    case */
  377.         tempop[j++]    = toupper (Label[i++]);
  378.     tempop[j] = '\0';
  379.  
  380.     if (!Pass2) {            /* Pass    1 */
  381.         if (Label[0] != '\0') {             /* Need a label */
  382.         templong = HeapLim - Heap;    /* Offset to text */
  383.         if (!ReadSymTab    (tempop))    /* Save    MACRO name */
  384.             AddSymTab (tempop, 0L, templong, LineCount,    8);
  385.         AddMacLine (Line);        /* Save    MACRO stmt. */
  386.  
  387.         while (strcmp (OpCode, "ENDM")) {
  388.             if (LineParts (dummy))
  389.             break;            /* Premature EOF */
  390.             AddMacLine (Line);        /* Store a line    */
  391.         }
  392.         }
  393.     } else {            /* Pass    2 */
  394.         if (Label[0] == '\0')
  395.         Error (0, NeedLab);        /* Need    a label    */
  396.         else {
  397.         ReadSymTab (tempop);
  398.         if (Sym->Defn != LineCount) {
  399.             Error (LabLoc, DupMac);    /* Duplicate MACRO */
  400.             AddRef (LineCount);
  401.         }
  402.         }
  403.         if (!SuppList)
  404.         WriteListLine (List);        /* Echo    MACRO */
  405.  
  406.         while (1) {
  407.         if (LineParts (dummy)) {
  408.             Error (OpLoc, NoENDM);    /* Premature EOF */
  409.             break;
  410.         } else {
  411.             if (strcmp (OpCode,    "ENDM") == 0)
  412.             break;
  413.             if (!SuppList)
  414.             WriteListLine (List);    /* Echo    a line */
  415.         }
  416.         }
  417.     }
  418.  
  419.     return (Macro);
  420.     }
  421.  
  422.     if (strcmp (OpCode,    "IFEQ") == 0) {                 /* IFEQ */
  423.     ObjSrc = GetValue (SrcOp, SrcLoc);
  424.     if (ObjSrc != 0)
  425.         SkipNest++;        /* Skip    to the next ENDC */
  426.     return (If);
  427.     }
  428.     if (strcmp (OpCode,    "IFNE") == 0) {                 /* IFNE */
  429.     ObjSrc = GetValue (SrcOp, SrcLoc);
  430.     if (ObjSrc == 0)
  431.         SkipNest++;
  432.     return (If);
  433.     }
  434.     if (strcmp (OpCode,    "IFGT") == 0) {                 /* IFGT */
  435.     ObjSrc = GetValue (SrcOp, SrcLoc);
  436.     if (ObjSrc <= 0)
  437.         SkipNest++;
  438.     return (If);
  439.     }
  440.     if (strcmp (OpCode,    "IFGE") == 0) {                 /* IFGE */
  441.     ObjSrc = GetValue (SrcOp, SrcLoc);
  442.     if (ObjSrc < 0)
  443.         SkipNest++;
  444.     return (If);
  445.     }
  446.     if (strcmp (OpCode,    "IFLT") == 0) {                 /* IFLT */
  447.     ObjSrc = GetValue (SrcOp, SrcLoc);
  448.     if (ObjSrc >= 0)
  449.         SkipNest++;
  450.     return (If);
  451.     }
  452.     if (strcmp (OpCode,    "IFLE") == 0) {                 /* IFLE */
  453.     ObjSrc = GetValue (SrcOp, SrcLoc);
  454.     if (ObjSrc > 0)
  455.         SkipNest++;
  456.     return (If);
  457.     }
  458.     if (strcmp (OpCode,    "IFC") == 0) {                  /* IFC */
  459.     if (strcmp (SrcOp, DestOp) != 0)
  460.         SkipNest++;
  461.     return (If);
  462.     }
  463.     if (strcmp (OpCode,    "IFNC") == 0) {                 /* IFNC */
  464.     if (strcmp (SrcOp, DestOp) == 0)
  465.         SkipNest++;
  466.     return (If);
  467.     }
  468.     if (strcmp (OpCode,    "IFD") == 0) {                  /* IFD */
  469.     if (ReadSymTab (SrcOp))
  470.         AddRef (LineCount);
  471.     if (DefLine2 > LineCount)
  472.         SkipNest++;
  473.     return (If);
  474.     }
  475.     if (strcmp (OpCode,    "IFND") == 0) {                 /* IFND */
  476.     if (ReadSymTab (SrcOp))
  477.         AddRef (LineCount);
  478.     if (DefLine2 <=    LineCount)
  479.         SkipNest++;
  480.     return (If);
  481.     }
  482.  
  483.     if ((strcmp    (OpCode, "ENDC") == 0)                  /* ENDC */
  484.     || (strcmp (OpCode,    "ENDIF") == 0))                 /* ENDIF */
  485.     return (EndC);            /* LineParts will take care of it */
  486.  
  487.     if ((strcmp    (OpCode, "CODE") == 0)                  /* CODE */
  488.     || (strcmp (OpCode,    "DATA") == 0)                   /* DATA */
  489.     || (strcmp (OpCode,    "BSS") == 0)) {                 /* BSS */
  490.     if (SFormat)
  491.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  492.     DoSection (SrcOp, SrcLoc, OpCode, OpLoc, DestOp, DestLoc);
  493.     return (Section);        /* Treat as SECTION */
  494.     }
  495.     if (strcmp (OpCode,    "CSEG") == 0) {                 /* CSEG */
  496.     if (SFormat)
  497.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  498.     DoSection (SrcOp, SrcLoc, "CODE", OpLoc, DestOp, DestLoc);
  499.     return (Section);        /* Treat as CODE */
  500.     }
  501.     if (strcmp (OpCode,    "DSEG") == 0) {                 /* DSEG */
  502.     if (SFormat)
  503.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  504.     DoSection (SrcOp, SrcLoc, "DATA", OpLoc, DestOp, DestLoc);
  505.     return (Section);        /* Treat as DATA */
  506.     }
  507.  
  508.     if (strcmp (OpCode,    "SECTION") == 0) {              /* SECTION */
  509.     if (SFormat)
  510.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  511.     tempop[0] = '\0';
  512.     j = DestLoc + strlen (DestOp);    /* Check for flags */
  513.     if (Line[j] == ',') {
  514.         j++;
  515.         GetField (Line, j, tempop);    /* Get specification */
  516.     }
  517.     DoSection (SrcOp, SrcLoc, DestOp, DestLoc, tempop, j);
  518.     return (Section);
  519.     }
  520.  
  521.     if (strcmp (OpCode,    "IDNT") == 0) {                 /* IDNT */
  522.     i = SrcLoc;
  523.     if (Line[i] == '"')
  524.         i++;        /* Ignore quotation marks */
  525.     j = 0;
  526.     while ((Line[i]    != ' ') && (Line[i] != '"') && (Line[i] != '\0'))
  527.         IdntName[j++] = Line[i++];
  528.     IdntName[j] = '\0';
  529.     return (Idnt);
  530.     }
  531.  
  532.     if (strcmp (OpCode,    "DCB") == 0) {                  /* DCB */
  533.     if ((Size == Word) || (Size == Long))
  534.         AddrCnt = AddrBndW (AddrCnt);
  535.     ObjSrc = GetValue (SrcOp, SrcLoc);    /* Replication factor */
  536.     if (DefLine2 > LineCount) {
  537.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  538.         ObjSrc = 0;
  539.     }
  540.     if (Hunk2 != ABSHUNK) {
  541.         Error (SrcLoc, AbsReq);    /* Must    be absolute! */
  542.         ObjSrc = 0;
  543.     }
  544.     ObjDest    = GetValue (DestOp, DestLoc);    /* Value to replicate */
  545.     Dest.Hunk = Hunk2;
  546.     for (i = 0; i <    ObjSrc;    i++) {
  547.         if (nX >= MAXLINE) {
  548.         Error (SrcLoc, DCOflo);        /* ObjString overflowed    */
  549.         break;
  550.         }
  551.         if (Dest.Hunk != ABSHUNK) {
  552.         templong = AddrCnt + nX;    /* Relocatable */
  553.         PutRel (templong, Hunk2, Size);
  554.         }
  555.         if (Size ==    4) {
  556.         ObjString[nX++]    = (ObjDest >> 24) & 0x00FF;
  557.         ObjString[nX++]    = (ObjDest >> 16) & 0x00FF;
  558.         }
  559.         if (Size >=    2)
  560.         ObjString[nX++]    = (ObjDest >> 8) & 0x00FF;
  561.         ObjString[nX++] = ObjDest &    0x00FF;
  562.     }
  563.     AddrAdv    = InstSize = nX;
  564.     PrntAddr = MakeHunk = TRUE;
  565.     return (DCB);
  566.     }
  567.  
  568.     if (strcmp (OpCode,    "EQUR") == 0) {                 /* EQUR */
  569.     if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
  570.         Error (SrcLoc, AddrErr);    /* Not a valid register    */
  571.     if (Label[0] ==    '\0')
  572.         Error (0, NeedLab);        /* Need    a label    */
  573.     else {
  574.         if (!ReadSymTab (Label))    /* Make    a new entry */
  575.         AddSymTab (Label, (long) i, 0L,    LineCount, 0x20);
  576.         GotEqur = TRUE;        /* We have at least one    EQUR */
  577.     }
  578.     return (Equr);
  579.     }
  580.  
  581.     if (strcmp (OpCode,    "REG") == 0) {                  /* REG */
  582.     if (Label[0] ==    '\0')
  583.         Error (0, NeedLab);        /* Need    a label    */
  584.     else {
  585.         i =    GetMultReg (SrcOp, FALSE, SrcLoc);
  586.         if (!ReadSymTab (Label))    /* Make    a new entry */
  587.         AddSymTab (Label, (long) i, 0L,    LineCount, 0x40);
  588.         GotEqur = TRUE;        /* We have at least one    EQUR */
  589.     }
  590.     return (Reg);
  591.     }
  592.  
  593.     return (None);                /* Not a directive */
  594. }
  595.  
  596.  
  597.  
  598. DoSection (name, nameloc, type,    typeloc, flags,    flagloc)
  599. char *name, *type, *flags;
  600. int nameloc, typeloc, flagloc;
  601. /* Processes SECTION directive or equivalent */
  602. {
  603.     static long    HunkPos;    /* Seek    address    of start of section */
  604.     register int i;
  605.     long newflags, templong;
  606.     char tempop[MAXLINE];
  607.  
  608.     PrntAddr = TRUE;
  609.  
  610.     for    (i = 0;    type[i]; i++)        /* Convert section type    */
  611.     type[i]    = toupper (type[i]);    /*  to upper case */
  612.     if ((type[0] == '\0') || (strcmp (type, "CODE") == 0))
  613.     newflags = HunkCode;        /* Code    section    */
  614.     else if (strcmp (type, "DATA") == 0)
  615.     newflags = HunkData;        /* Data    section    */
  616.     else if (strcmp (type, "BSS") == 0)
  617.     newflags = HunkBSS;        /* BSS section */
  618.     else {
  619.     Error (typeloc,    OperErr);    /* Invalid type    */
  620.     strcpy (type, "CODE");
  621.     newflags = HunkCode;        /* Make    it CODE    */
  622.     }
  623.     newflags <<= 16;    /* Shift to high-order 16 bits */
  624.  
  625.     if (flags[0]) {
  626.     for (i = 0; flags[i]; i++)        /* Convert flags */
  627.         flags[i] = toupper (flags[i]);    /*  to upper case */
  628.     if (strcmp (flags, "CHIP") == 0)
  629.         newflags |=    MEMF_CHIP;        /* CHIP    memory */
  630.     else if    (strcmp    (flags,    "FAST") == 0)
  631.         newflags |=    MEMF_FAST;        /* FAST    memory */
  632.     else
  633.         Error (flagloc, OperErr);        /* Invalid - ignore */
  634.     }
  635.  
  636.     AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word */
  637.     strcpy (tempop, "  ");              /* Two leading blanks */
  638.     templong = (newflags & 0xFFFF0000) >> 16;
  639.     if (templong == HunkCode)        /* Make    section    name */
  640.     strcat (tempop,    "C");           /*  unique across types */
  641.     else if (templong == HunkData)
  642.     strcat (tempop,    "D");
  643.     else
  644.     strcat (tempop,    "B");
  645.     strcat (tempop, name);        /* Section name    */
  646.     if (ReadSymTab (tempop)) {        /* Scan    for section name */
  647.     if (HunkType !=    HunkNone) {
  648.         if (Pass2) {
  649.         AddRef (LineCount);
  650.         DumpSdata (Srec);    /* Finish the previous hunk */
  651.         if (!MakeHunk)        /* If it was a null hunk,   */
  652.             fseek (Srec, HunkPos, 0);    /*  overwrite it.   */
  653.         }
  654.         Sect->Val =    AddrCnt;    /* End of old section */
  655.         SectLine = LineCount;    /* Start of new    section    */
  656.     } else {
  657.         SectLine = 1;        /* Start of first section */
  658.     }
  659.     Sect = Sym;            /* Point to new    section    */
  660.     AddrCnt    = SectStart = Sym->Val;    /* Continuation    */
  661.     TempAddr = StartAddr = AddrCnt;
  662.     CurrHunk = Sym->Hunk & 0x0000FFFFL;        /* Hunk no.    */
  663.     HunkType = (Sym->Hunk &    0x3FFF0000L) >>    16; /* Type */
  664.     HunkFlags = Sym->Hunk &    0xC0000000L;        /* Flags */
  665.     if (Pass2 && !SFormat) {        /* Start a new hunk */
  666.         HunkPos = ftell (Srec);
  667.         templong = HunkName;
  668.         putl (Srec,    templong);
  669.         if (name[0])
  670.         DumpName (Srec,    name, 0L);    /* Hunk    name */
  671.         else
  672.         DumpName (Srec,    " ", 0L);
  673.         putl (Srec,    HunkType);    /* Hunk    type */
  674.         LenPos = ftell (Srec);    /* Hunk    length goes here */
  675.         putl (Srec,    0L);        /* For now, set    it to zero */
  676.     }
  677.     MakeHunk = FALSE;        /* We don't have anything yet */
  678.     return;
  679.     }
  680.  
  681.     if (Pass2) {
  682.     Error (OpLoc, ManySect);    /* Table overflowed in pass 1 */
  683.     return;
  684.     }
  685.     if (NextHunk >= ABSHUNK)        /* Set up a new    table entry */
  686.     return;                /* Section table overflow */
  687.  
  688.     if (HunkType != HunkNone) {
  689.     Sect->Val = AddrCnt;        /* End of old section */
  690.     SectLine = LineCount;        /* Starting line number    */
  691.     } else {
  692.     SectLine = 1;            /* Start of first section */
  693.     }
  694.     AddrCnt = SectStart    = 0L;        /* Reset location counter */
  695.     TempAddr = StartAddr = AddrCnt;
  696.     HunkType = (newflags & 0x3FFF0000L)    >> 16;    /* Type    */
  697.     HunkFlags =    newflags & 0xC0000000L;        /* Flags */
  698.     CurrHunk = NextHunk++;        /* Bump    next hunk number */
  699.     newflags |=    CurrHunk;        /* Add hunk number */
  700.     AddSymTab (tempop, 0L, newflags, LineCount,    16);    /* New entry */
  701.     Sect = Sym;                /* Pointer to new entry    */
  702.     MakeHunk = FALSE;            /* We don't have anything yet */
  703.     return;
  704. }
  705.